package com.crl.rcdp.gateway.filter;

import com.cars.util.json.JsonUtil;
import com.cars.util.request.RequestUtil;
import com.cars.util.string.StringUtil;
import com.crl.rcdp.sys.model.SysErrorLog;
import com.crl.rcdp.sys.service.SysErrorLogService;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.util.StreamUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * @description:
 * @author: 孔垂云
 * @version: 1.0
 * @date: 2020/8/11 0:28
 */
public class TimeCostPostFilter extends ZuulFilter {
    private static final String START_TIME_KE = "start_time";
    @Autowired
    private SysErrorLogService sysErrorLogService;

    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        long startTime = (long) RequestContext.getCurrentContext().get(START_TIME_KE);
        System.out.println("请求完成,耗时{}秒" + (System.currentTimeMillis() - startTime) / 1000);
        int consume = (int) (System.currentTimeMillis() - startTime);
        //如果请求时间超过3秒，记录到数据库
        SysErrorLog sysErrorLog = new SysErrorLog();
        sysErrorLog.setPath(request.getServletPath());
        sysErrorLog.setClientIp(StringUtil.getIp(request));
        sysErrorLog.setRequestParam(RequestUtil.getBody(request));//请求参数
        if (sysErrorLog.getRequestParam().length() > 2000) {
            sysErrorLog.setRequestParam(sysErrorLog.getRequestParam().substring(0, 2000));
        }
//        sysErrorLog.setReturnCode(returnCode);
        sysErrorLog.setTimeConsuming(consume);
        if (consume > 3000) {
            sysErrorLog.setErrorType(1);//请求过慢
        }
        String authorization = request.getHeader("Authorization");//获取authorization
        String appid = request.getHeader("appid");//appid
        String accessToken = request.getHeader("accessToken");//accessToken
        sysErrorLog.setClientIp(StringUtil.getIp(request));//ip地址
        sysErrorLog.setAuthType(FilterUtil.getAuthType(authorization, accessToken, appid));//授权方式
        sysErrorLog.setOwner(FilterUtil.getOwner(authorization, accessToken, appid));//owner
        String responseBody = currentContext.getResponseBody();
        if (responseBody == null) {
            ByteArrayOutputStream byteArrayOutputStream = RequestUtil.cloneInputStream(currentContext.getResponseDataStream());
            if (byteArrayOutputStream != null) {
                try {
                    InputStream copyResponseDataStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                    InputStream copyResponseDataStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                    responseBody = StreamUtils.copyToString(copyResponseDataStream1, StandardCharsets.UTF_8);
                    currentContext.setResponseDataStream(copyResponseDataStream);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        String returnCode = JsonUtil.getNodeStr(responseBody, "returnCode");
        if (StringUtil.isNotNullOrEmpty(returnCode) && !returnCode.equals("00200")) {
            sysErrorLog.setErrorType(2);
        }
        sysErrorLog.setReturnCode(returnCode);
        if (responseBody.length() > 2000) {
            responseBody = responseBody.substring(0, 2000);
        }
        sysErrorLog.setResponse(responseBody);
        sysErrorLogService.add(sysErrorLog);
        return null;
    }
}
